<!DOCTYPE html>

<html lang="
zh-CN"
    >

        <head>
            
                <title>
                    
                        JAVA-Spring5 -
                            
                                shanX&#39;s Blog
                </title>
                <meta charset="UTF-8">
                <meta name="description" content="">
                <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
                
                    

                        <link rel="shortcut icon" href="/image/author.png" type="image/png" />
                        <meta name="description" content="Spring5">
<meta property="og:type" content="article">
<meta property="og:title" content="JAVA-Spring5">
<meta property="og:url" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/index.html">
<meta property="og:site_name" content="shanX&#39;s Blog">
<meta property="og:description" content="Spring5">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180016435.png">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180025728.png">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180035980.png">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180055895.png">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180116257.png">
<meta property="og:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180128654.png">
<meta property="article:published_time" content="2021-05-03T15:00:02.000Z">
<meta property="article:modified_time" content="2022-04-07T17:25:27.688Z">
<meta property="article:author" content="shanX">
<meta property="article:tag" content="java基础">
<meta property="article:tag" content="spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/image/article/JAVA-Spring5-20210503/20200628180016435.png">
                            <link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/highlight.js@9.15.8/styles/atom-one-dark.css,gh/theme-nexmoe/hexo-theme-nexmoe@latest/source/lib/mdui_043tiny/css/mdui.css,gh/theme-nexmoe/hexo-theme-nexmoe@latest/source/lib/iconfont/iconfont.css,gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css?v=233"
                                crossorigin>
                            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/css/justifiedGallery.min.css">
                            <!--适用于 Retina 屏的 iPad-->
                            <link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png">
                            <!--适用于 Retina 屏的 iPhone-->
                            <link rel="apple-touch-icon-precomposed" sizes="120x120" href="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png">
                            <!--适用于非 Retina 屏的 iPad-->
                            <link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png">
                            <!--适用于非 Retina 屏的 iPhone-->
                            <link rel="apple-touch-icon-precomposed" href="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png">
                            
                                <link rel="stylesheet" href="//at.alicdn.com/t/font_2490857_fmjyoao96km.css">
                                
                                    <link rel="stylesheet" href="/css/style.css?v=1649858550901">
        <meta name="generator" content="Hexo 5.4.0"></head>

        <body class="mdui-drawer-body-left">
            
                <div id="nexmoe-background">
                    <div class="nexmoe-bg" style="background-image: url(https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/cover/5887c2f1-b191-4890-aab5-2ce62d9955df.jpg)"></div>
                    <div class="mdui-appbar mdui-shadow-0">
                        <div class="mdui-toolbar">
                            <a mdui-drawer="{target: '#drawer', swipe: true}" title="menu" class="mdui-btn mdui-btn-icon mdui-ripple"><i class="mdui-icon nexmoefont icon-menu"></i></a>
                            <div class="mdui-toolbar-spacer"></div>
                            <!--<a href="javascript:;" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">search</i></a>-->
                            <a href="/" title="shanX" class="mdui-btn mdui-btn-icon"><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png" alt="shanX"></a>
                        </div>
                    </div>
                </div>
                <div id="nexmoe-header">
                    <div class="nexmoe-drawer mdui-drawer" id="drawer">
    <div class="nexmoe-avatar mdui-ripple">
        <a href="/" title="shanX">
            <img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/author.png" alt="shanX" alt="shanX">
        </a>
    </div>
    <div class="nexmoe-count nexmoe-widget-wrap">
        <div><span>文章</span>30</div>
        <div><span>标签</span>16</div>
        <div><span>分类</span>8</div>
    </div>
    <div class="nexmoe-list mdui-list nexmoe-widget-wrap" mdui-collapse="{accordion: true}">
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/" title="回到首页">
            <i class="mdui-list-item-icon nexmoefont icon-home"></i>
            <div class="mdui-list-item-content">
                回到首页
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/archives.html" title="文章归档">
            <i class="mdui-list-item-icon nexmoefont icon-container"></i>
            <div class="mdui-list-item-content">
                文章归档
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/cesium-test/index.html" title="Cesium">
            <i class="mdui-list-item-icon nexmoefont icon-Cesium-copy"></i>
            <div class="mdui-list-item-content">
                Cesium
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/cesium-covid/index.html" title="全球疫情">
            <i class="mdui-list-item-icon nexmoefont icon-areachart"></i>
            <div class="mdui-list-item-content">
                全球疫情
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/about.html" title="关于博客">
            <i class="mdui-list-item-icon nexmoefont icon-info-circle"></i>
            <div class="mdui-list-item-content">
                关于博客
            </div>
        </a>
        
    </div>
    <aside id="nexmoe-sidebar">
  
  <div class="nexmoe-widget-wrap">
    <div class="nexmoe-widget nexmoe-search">
        <form id="search_form" action_e="https://cn.bing.com/search?q=rhymexmove.github.io" onsubmit="return search();">
            <label><input id="search_value" name="q" type="search" placeholder="搜索"></label>
        </form>
    </div>
</div>
  
  <div class="nexmoe-widget-wrap">
    <div class="nexmoe-widget nexmoe-social">
        <a class="mdui-ripple" href="https://space.bilibili.com/20666214" target="_blank" mdui-tooltip="{content: '哔哩哔哩'}" style="color: rgb(231, 106, 141);background-color: rgba(231, 106, 141, .15);">
            <i class="nexmoefont icon-bilibili"></i>
        </a><a class="mdui-ripple" href="https://github.com/RhymeXmove/" target="_blank" mdui-tooltip="{content: 'GitHub'}" style="color: rgb(231, 106, 141);background-color: rgba(231, 106, 141, .15);">
            <i class="nexmoefont icon-github"></i>
        </a><a class="mdui-ripple" href="https://gitee.com/shanxin123/" target="_blank" mdui-tooltip="{content: 'Gitee'}" style="color: rgb(220,20,60);background-color: rgba(220,20,60, .15);">
            <i class="nexmoefont icon-gitee"></i>
        </a>
    </div>
</div>
  
  
    <div class="nexmoe-widget-wrap">
        <h3 class="nexmoe-widget-title">
            文章分类
        </h3>
        <div class="nexmoe-widget">

            <ul class="category-list">

                


                    

                        

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/mysql/">
                                    -mysql
                                </a>
                                <span class="category-list-count">1</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/Cesium/">
                                    Cesium
                                </a>
                                <span class="category-list-count">3</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/DB/">
                                    DB
                                </a>
                                <span class="category-list-count">2</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/Leetcode/">
                                    Leetcode
                                </a>
                                <span class="category-list-count">4</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/Vue/">
                                    Vue
                                </a>
                                <span class="category-list-count">2</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/blog搭建/">
                                    blog搭建
                                </a>
                                <span class="category-list-count">1</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/java/">
                                    java
                                </a>
                                <span class="category-list-count">12</span>
                            </li>

                            

                            <li class="category-list-item">
                                <a class="category-list-link" href="/categories/资源/">
                                    资源
                                </a>
                                <span class="category-list-count">1</span>
                            </li>

                            
            </ul>

        </div>
    </div>
    
  
  
  <div class="nexmoe-widget-wrap">
    <div id="randomtagcloud" class="nexmoe-widget tagcloud nexmoe-rainbow">
      <a href="/tags/DB/" style="font-size: 10px;">-DB</a> <a href="/tags/Cesium/" style="font-size: 12.5px;">Cesium</a> <a href="/tags/GIS/" style="font-size: 10px;">GIS</a> <a href="/tags/Leetcode/" style="font-size: 15px;">Leetcode</a> <a href="/tags/Vue/" style="font-size: 12.5px;">Vue</a> <a href="/tags/blog%E6%90%AD%E5%BB%BA/" style="font-size: 10px;">blog搭建</a> <a href="/tags/echart/" style="font-size: 10px;">echart</a> <a href="/tags/java/" style="font-size: 10px;">java</a> <a href="/tags/java%E5%9F%BA%E7%A1%80/" style="font-size: 20px;">java基础</a> <a href="/tags/mysql/" style="font-size: 10px;">mysql</a> <a href="/tags/spring/" style="font-size: 10px;">spring</a> <a href="/tags/vue/" style="font-size: 10px;">vue</a> <a href="/tags/%E6%89%B9%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7/" style="font-size: 10px;">批处理工具</a> <a href="/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/" style="font-size: 10px;">数据库</a> <a href="/tags/%E7%8B%82%E7%A5%9E%E8%AF%B4/" style="font-size: 17.5px;">狂神说</a> <a href="/tags/%E8%B5%84%E6%BA%90/" style="font-size: 10px;">资源</a>
    </div>
    
  </div>

  
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">文章归档</h3>
    <div class="nexmoe-widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/">2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/">2021</a><span class="archive-list-count">29</span></li></ul>
    </div>
  </div>



  
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">最新文章</h3>
    <div class="nexmoe-widget">
      <ul>
        
          <li>
            <a href="/2022/04/13/7533e8f3cb4c/">mysql查询数据库内全部表名；查询表内全部字段名</a>
          </li>
        
          <li>
            <a href="/2021/09/26/ee931b51117c/">什么是计算机图形学？</a>
          </li>
        
          <li>
            <a href="/2021/09/08/9adeea845004/">中国城市坐标(包含市辖区)</a>
          </li>
        
          <li>
            <a href="/2021/08/31/7ba201dda6cb/">Cesium billboard贴地形表</a>
          </li>
        
          <li>
            <a href="/2021/08/09/0d3ed7d31d83/">Vue中使用Vue-jsonp请求jsonp数据</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
    <div class="nexmoe-copyright">
        &copy; 2022 shanX
        Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
        & <a href="https://github.com/theme-nexmoe/hexo-theme-nexmoe" target="_blank">Nexmoe</a>
        
    </div>
</div><!-- .nexmoe-drawer -->
                </div>
                <div id="nexmoe-content">
                    <div class="nexmoe-primary">
                        <div class="nexmoe-post">

  <div class="nexmoe-post-right">
    
      <div class="nexmoe-fixed">
        <div class="nexmoe-valign">
            <div class="nexmoe-toc">
                
                
                  <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Spring5"><span class="toc-number">1.</span> <span class="toc-text">Spring5</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AE%80%E4%BB%8B"><span class="toc-number">1.1.</span> <span class="toc-text">简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BC%98%E7%82%B9"><span class="toc-number">1.2.</span> <span class="toc-text">优点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%84%E6%88%90"><span class="toc-number">1.3.</span> <span class="toc-text">组成</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8B%93%E5%B1%95"><span class="toc-number">1.4.</span> <span class="toc-text">拓展</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#IOC%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC"><span class="toc-number">2.</span> <span class="toc-text">IOC理论推导</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#IOC%E6%9C%AC%E8%B4%A8"><span class="toc-number">2.1.</span> <span class="toc-text">IOC本质</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#HelloSpring"><span class="toc-number">3.</span> <span class="toc-text">HelloSpring</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#IOC%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F"><span class="toc-number">4.</span> <span class="toc-text">IOC创建对象的方式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Spring%E9%85%8D%E7%BD%AE"><span class="toc-number">5.</span> <span class="toc-text">Spring配置</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%AB%E5%90%8D"><span class="toc-number">5.1.</span> <span class="toc-text">别名</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Bean%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">5.2.</span> <span class="toc-text">Bean的配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#import"><span class="toc-number">5.3.</span> <span class="toc-text">import</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5-DI"><span class="toc-number">6.</span> <span class="toc-text">依赖注入 (DI)</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%84%E9%80%A0%E5%99%A8%E6%B3%A8%E5%85%A5"><span class="toc-number">6.1.</span> <span class="toc-text">构造器注入</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5-%E3%80%90%E9%87%8D%E7%82%B9%E3%80%91"><span class="toc-number">6.2.</span> <span class="toc-text">Set方式注入 【重点】</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8B%93%E5%B1%95%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.3.</span> <span class="toc-text">拓展方式注入</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Bean%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">6.4.</span> <span class="toc-text">Bean的作用域</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Bean%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.</span> <span class="toc-text">Bean的自动装配</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95"><span class="toc-number">7.1.</span> <span class="toc-text">测试</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#byName%E8%87%AA%E5%AE%9A%E8%A3%85%E9%85%8D"><span class="toc-number">7.2.</span> <span class="toc-text">byName自定装配</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#byTpye%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.3.</span> <span class="toc-text">byTpye自动装配</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.4.</span> <span class="toc-text">使用注解实现自动装配</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Autowired"><span class="toc-number">7.4.1.</span> <span class="toc-text">@Autowired</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Resource"><span class="toc-number">7.4.2.</span> <span class="toc-text">@Resource</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Java%E7%B1%BB%E5%AE%9E%E7%8E%B0Spring%E9%85%8D%E7%BD%AE"><span class="toc-number">8.</span> <span class="toc-text">Java类实现Spring配置</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%9D%A2%E5%90%91%E5%88%87%E9%9D%A2%E7%BC%96%E7%A8%8BAOP%EF%BC%88%E9%87%8D%E7%82%B9%EF%BC%89"><span class="toc-number">9.</span> <span class="toc-text">面向切面编程AOP（重点）</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Spring-API%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0"><span class="toc-number">9.1.</span> <span class="toc-text">Spring API接口实现</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AE%9E%E7%8E%B0AOP%EF%BC%88%E4%B8%BB%E8%A6%81%E6%98%AF%E5%88%87%E9%9D%A2%E5%AE%9A%E4%B9%89%EF%BC%89%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8"><span class="toc-number">9.2.</span> <span class="toc-text">自定义实现AOP（主要是切面定义）推荐使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0AOP"><span class="toc-number">9.3.</span> <span class="toc-text">使用注解实现AOP</span></a></li></ol></li></ol>
                
            </div>
        </div>
      </div>
    
  </div>

  <article>
    
        <div class="nexmoe-post-cover" style="padding-bottom: NaN%;"> 
            <img data-src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/cover/Spring.png" data-sizes="auto" alt="JAVA-Spring5" class="lazyload">
            <h1>JAVA-Spring5</h1>
        </div>
    
    
    <div class="nexmoe-post-meta nexmoe-rainbow-fill" style="margin:10px 0!important;">
    <a><i class="nexmoefont icon-calendar-fill"></i>2021年05月03日</a>
    <a><i class="nexmoefont icon-areachart"></i>5.3k 字</a>
    <a><i class="nexmoefont icon-time-circle-fill"></i>大概 26 分钟</a>
</div>

    <h1 id="Spring5"><a href="#Spring5" class="headerlink" title="Spring5"></a>Spring5</h1><span id="more"></span>

<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>春天 —&gt;给软件行业带来了春天<br>2002年，Rod Jahnson首次推出了Spring框架雏形interface21框架。<br>2004年3月24日，Spring框架以interface21框架为基础，经过重新设计，发布了1.0正式版。<br>Rod Johnson的学历 , 他是悉尼大学的博士，然而他的专业不是计算机，而是音乐学。<br>Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术<br>官方下载地址 ： <a target="_blank" rel="noopener" href="https://repo.spring.io/libs-release-local/org/springframework/spring/">https://repo.spring.io/libs-release-local/org/springframework/spring/</a></p>
<pre><code class="xml">&lt;!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
    &lt;version&gt;5.2.0.RELEASE&lt;/version&gt;
&lt;/dependency&gt;
&lt;!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework&lt;/groupId&gt;
    &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
    &lt;version&gt;5.2.0.RELEASE&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<h2 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h2><ul>
<li>Spring是一个开源免费的框架 (容器)！</li>
<li>Spring是一个轻量级的框架 , 非侵入式的</li>
<li><strong>控制反转 IoC , 面向切面 Aop</strong></li>
<li>对事务的支持 , 对框架整合的支持</li>
</ul>
<p><strong>Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器（框架）。</strong></p>
<h2 id="组成"><a href="#组成" class="headerlink" title="组成"></a>组成</h2><p>Spring 框架是一个分层架构，由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上，核心容器定义了创建、配置和管理 bean 的方式 .</p>
<p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180016435.png"></p>
<p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180025728.png"></p>
<ul>
<li>核心容器：核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory，它是工厂模式的实现。BeanFactory 使用控制反转（IOC） 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。</li>
<li>Spring 上下文：Spring 上下文是一个配置文件，向 Spring 框架提供上下文信息。Spring 上下文包括企业服务，例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。</li>
<li>Spring AOP：通过配置管理特性，Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以，可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP，不用依赖组件，就可以将声明性事务管理集成到应用程序中。</li>
<li>Spring DAO：JDBC DAO 抽象层提供了有意义的异常层次结构，可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理，并且极大地降低了需要编写的异常代码数量（例如打开和关闭连接）。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。</li>
<li>Spring ORM：Spring 框架插入了若干个 ORM 框架，从而提供了 ORM 的对象关系工具，其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。</li>
<li>Spring Web 模块：Web 上下文模块建立在应用程序上下文模块之上，为基于 Web 的应用程序提供了上下文。所以，Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。</li>
<li>Spring MVC 框架：MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口，MVC 框架变成为高度可配置的，MVC 容纳了大量视图技术，其中包括 JSP、Velocity、Tiles、iText 和 POI。</li>
</ul>
<h2 id="拓展"><a href="#拓展" class="headerlink" title="拓展"></a>拓展</h2><p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180035980.png"></p>
<ul>
<li>Spring Boot<ul>
<li>一个快速开发的脚手架</li>
<li>基于SpringBoot可以快速的开发单个微服务</li>
</ul>
</li>
<li>Spring Cloud<ul>
<li>Spring Cloud是基于SpringBoot实现的</li>
</ul>
</li>
</ul>
<h1 id="IOC理论推导"><a href="#IOC理论推导" class="headerlink" title="IOC理论推导"></a>IOC理论推导</h1><ol>
<li>UserDao 接口</li>
</ol>
<pre><code class="java">public interface UserDao &#123;
   void getUser();
&#125;
</code></pre>
<ol start="2">
<li>UserDaoImpl 实现类</li>
</ol>
<pre><code class="java">public class UserDaoImpl implements UserDao &#123;
   @Override
   public void getUser() &#123;
       System.out.println(&quot;获取用户数据&quot;);
  &#125;
&#125;
</code></pre>
<ol start="3">
<li>UserService 业务接口</li>
</ol>
<pre><code class="java">public interface UserService &#123;
   void getUser();
&#125;
</code></pre>
<ol start="4">
<li>UserServiceImpl 业务实现类</li>
</ol>
<pre><code class="java">public class UserServiceImpl implements UserService &#123;
   private UserDao userDao = new UserDaoImpl();

   public void getUser() &#123;
       userDao.getUser();
  &#125;
&#125;
</code></pre>
<ol start="5">
<li>测试一下</li>
</ol>
<pre><code class="java">@Test
public void test()&#123;
   UserService service = new UserServiceImpl();
   service.getUser();
&#125;
</code></pre>
<p>把Userdao的实现类增加一个 .</p>
<pre><code class="java">public class UserDaoMySqlImpl implements UserDao &#123;
   @Override
   public void getUser() &#123;
       System.out.println(&quot;MySql获取用户数据&quot;);
  &#125;
&#125;
</code></pre>
<p>紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现</p>
<pre><code class="java">public class UserServiceImpl implements UserService &#123;
   private UserDao userDao = new UserDaoMySqlImpl();

   @Override
   public void getUser() &#123;
       userDao.getUser();
  &#125;
&#125;
</code></pre>
<p><strong>代码量十分大，修改一次的成本十分昂贵！</strong></p>
<p>我们使用一个Set接口实现，已经发生了革命性的变化！</p>
<pre><code class="java">public class UserServiceImpl implements UserService &#123;
   private UserDao userDao;
    // 利用set实现
   public void setUserDao(UserDao userDao) &#123;
       this.userDao = userDao;
  &#125;

   @Override
   public void getUser() &#123;
       userDao.getUser();
  &#125;
&#125;
</code></pre>
<ul>
<li>之前，程序是主动创建对象，控制权在程序员手上！</li>
<li>使用了set注入后，程序不再具有主动性，而是变成了被动的接受对象！</li>
</ul>
<p>这种思想，从本质上解决了问题，我们程序员不用再去管对象的创建了。系统的耦合性大大降低，可以专注在业务的实现上！这是IOC的原型！</p>
<h2 id="IOC本质"><a href="#IOC本质" class="headerlink" title="IOC本质"></a>IOC本质</h2><p>控制反转IoC(Inversion of Control)，是一种设计思想，DI(依赖注入)是实现IoC的一种方法，也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中，对象的创建由程序自己控制，控制反转后将对象的创建转移给第三方，个人认为所谓控制反转就是：获得依赖对象的方式反转了。</p>
<p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180055895.png"></p>
<p>采用XML方式配置Bean的时候，Bean的定义信息是和实现分离的，而采用注解的方式可以把两者合为一体，Bean的定义信息直接以注解的形式定义在实现类中，从而达到了零配置的目的。</p>
<p><strong>控制反转是一种通过描述（XML或注解）并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器，其实现方法是依赖注入（Dependency Injection,DI）。</strong></p>
<h1 id="HelloSpring"><a href="#HelloSpring" class="headerlink" title="HelloSpring"></a>HelloSpring</h1><p>beans.xml</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&quot;&gt;

    &lt;!--使用spring创建对象，在spring中这些都称为bean--&gt;
    &lt;bean id=&quot;hello&quot; class=&quot;com.shan.pojo.Hello&quot;&gt;
        &lt;property name=&quot;str&quot; value=&quot;Spring&quot;/&gt;
    &lt;/bean&gt;

&lt;/beans&gt;
</code></pre>
<p>pojo.hello.java</p>
<pre><code class="java">package com.shan.pojo;

public class Hello &#123;
    private String str;

    public String getStr() &#123;
        return str;
    &#125;

    public void setStr(String str) &#123;
        this.str = str;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Hello&#123;&quot; +
                &quot;str=&#39;&quot; + str + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
<p>test</p>
<pre><code class="java">@Test
    public void test01()&#123;
        //获取spring的上下文对象
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);
        // 我们的对象现在都在spring管理了,我们要使用，直接去里面取出来就可以！
        Hello hello =(Hello) context.getBean(&quot;hello&quot;);
        System.out.println(hello);
    &#125;
</code></pre>
<h1 id="IOC创建对象的方式"><a href="#IOC创建对象的方式" class="headerlink" title="IOC创建对象的方式"></a>IOC创建对象的方式</h1><ol>
<li><p>使用无参构造创建对象，默认！</p>
</li>
<li><p>假设我们要使用有参构造创建对象。</p>
<ol>
<li><p>下标赋值</p>
<pre><code class="xml">&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg index=&quot;0&quot; value=&quot;7500000&quot;/&gt;
    &lt;constructor-arg index=&quot;1&quot; value=&quot;42&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
<li><p>构造参数类型</p>
<pre><code class="xml">&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg type=&quot;int&quot; value=&quot;7500000&quot;/&gt;
    &lt;constructor-arg type=&quot;java.lang.String&quot; value=&quot;42&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
<li><p>构造参数名</p>
<pre><code class="xml">&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg name=&quot;years&quot; value=&quot;7500000&quot;/&gt;
    &lt;constructor-arg name=&quot;ultimateAnswer&quot; value=&quot;42&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
</ol>
</li>
</ol>
<p>总结：在配置文件加载的时候，容器中管理的对象就已经初始化了</p>
<h1 id="Spring配置"><a href="#Spring配置" class="headerlink" title="Spring配置"></a>Spring配置</h1><h2 id="别名"><a href="#别名" class="headerlink" title="别名"></a>别名</h2><pre><code class="xml">&lt;!--设置别名：在获取Bean的时候可以使用别名获取--&gt;
&lt;alias name=&quot;userT&quot; alias=&quot;userNew&quot;/&gt;
</code></pre>
<h2 id="Bean的配置"><a href="#Bean的配置" class="headerlink" title="Bean的配置"></a>Bean的配置</h2><pre><code class="xml">&lt;!--bean就是java对象,由Spring创建和管理--&gt;

&lt;!--
   id : bean的标识符,要唯一,如果没有配置id,name就是默认标识符
   如果配置id,又配置了name,那么name是别名
   name可以设置多个别名,可以用逗号,分号,空格隔开
   如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;

   class : bean的全限定名=包名+类名
--&gt;
&lt;bean id=&quot;hello&quot; name=&quot;hello2 h2,h3;h4&quot; class=&quot;com.kuang.pojo.Hello&quot;&gt;
   &lt;property name=&quot;name&quot; value=&quot;Spring&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<h2 id="import"><a href="#import" class="headerlink" title="import"></a>import</h2><p>这个import,一般用于团队开发使用，他可以将多个配置文件，导入合并为一个；</p>
<p>假设，现在项目中有多个人开发，这三个人复制不同的类开发，不同的类需要注册在不同的bean中，我们可以利用import将所有人的beans.xml合并为一个总的！</p>
<p>applicationContext.xml</p>
<pre><code class="xml">&lt;import resource=&quot;&#123;path&#125;/beans.xml&quot;/&gt;
</code></pre>
<h1 id="依赖注入-DI"><a href="#依赖注入-DI" class="headerlink" title="依赖注入 (DI)"></a>依赖注入 (DI)</h1><h2 id="构造器注入"><a href="#构造器注入" class="headerlink" title="构造器注入"></a>构造器注入</h2><p>前面已经说过了</p>
<h2 id="Set方式注入-【重点】"><a href="#Set方式注入-【重点】" class="headerlink" title="Set方式注入 【重点】"></a>Set方式注入 【重点】</h2><ul>
<li>依赖注入：Set注入<ul>
<li>依赖：bean对象的创建依赖于容器</li>
<li>注入：bean对象中的所有属性，由容器来注入</li>
</ul>
</li>
</ul>
<ol>
<li><p>模拟环境搭建</p>
</li>
<li><p>两个实体类</p>
<pre><code class="java">@Data
public class Student &#123;

    private String name;
    private Address address;
    private String[] books;
    private List&lt;String&gt; hobbys;
    private Map&lt;String,String&gt; card;
    private Set&lt;String&gt; games;
    private String wife;
    private Properties info;
&#125;
</code></pre>
<pre><code class="java">@Data
public class Address &#123;
    private String address;
&#125;
</code></pre>
</li>
<li><p>配置 applicationContext.xml</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;address&quot; class=&quot;com.kuang.pojo.Address&quot;&gt;
        &lt;property name=&quot;address&quot; value=&quot;NJUPT9&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;student&quot; class=&quot;com.kuang.pojo.Student&quot;&gt;
        &lt;!--第一种，普通值注入，value--&gt;
        &lt;property name=&quot;name&quot; value=&quot;狂神&quot;/&gt;

        &lt;!--第二种,Bean注入--&gt;
        &lt;property name=&quot;address&quot; ref=&quot;address&quot;/&gt;

        &lt;!--数组--&gt;
        &lt;property name=&quot;books&quot;&gt;
            &lt;array&gt;
                &lt;value&gt;红楼&lt;/value&gt;
                &lt;value&gt;三国&lt;/value&gt;
            &lt;/array&gt;
        &lt;/property&gt;

        &lt;!--List--&gt;
        &lt;property name=&quot;hobbys&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;music&lt;/value&gt;
                &lt;value&gt;swimming&lt;/value&gt;
                &lt;value&gt;coding&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;

        &lt;!--Map--&gt;
        &lt;property name=&quot;card&quot;&gt;
            &lt;map&gt;
                &lt;entry key=&quot;身份证&quot; value=&quot;12312121212&quot;/&gt;
                &lt;entry key=&quot;银行卡&quot; value=&quot;678112121111000&quot;/&gt;
            &lt;/map&gt;
        &lt;/property&gt;

        &lt;!--Set--&gt;
        &lt;property name=&quot;games&quot;&gt;
            &lt;set&gt;
                &lt;value&gt;CF&lt;/value&gt;
                &lt;value&gt;LOL&lt;/value&gt;
                &lt;value&gt;GTA&lt;/value&gt;
            &lt;/set&gt;
        &lt;/property&gt;

        &lt;!--null--&gt;
        &lt;property name=&quot;wife&quot;&gt;
            &lt;null/&gt;
        &lt;/property&gt;

        &lt;!--Properties--&gt;
        &lt;property name=&quot;info&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;学号&quot;&gt;20190526&lt;/prop&gt;
                &lt;prop key=&quot;username&quot;&gt;root&lt;/prop&gt;
                &lt;prop key=&quot;password&quot;&gt;root&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
</li>
<li><p>测试</p>
<pre><code class="java">public class MyTest &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);
        Student student = (Student) context.getBean(&quot;student&quot;);
        System.out.println(student);
    &#125;
&#125;
</code></pre>
</li>
</ol>
<h2 id="拓展方式注入"><a href="#拓展方式注入" class="headerlink" title="拓展方式注入"></a>拓展方式注入</h2><p>我们可以使用p命名空间和c命名空间进行注入</p>
<p>官方解释：</p>
<p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180116257.png"></p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
       xmlns:c=&quot;http://www.springframework.org/schema/c&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;!--p命名空间注入，可以直接注入属性的值：property--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot; p:name=&quot;狂神&quot; p:age=&quot;18&quot;/&gt;

    &lt;!--c命名空间注入，通过构造器注入：construt-args--&gt;
    &lt;bean id=&quot;user2&quot; class=&quot;com.kuang.pojo.User&quot; c:name=&quot;狂神2&quot; c:age=&quot;11&quot;/&gt;

&lt;/beans&gt;
</code></pre>
<p><strong>注意点：p命名和c命名空间不能直接使用，需要导入xml约束！</strong></p>
<pre><code class="xml">xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
xmlns:c=&quot;http://www.springframework.org/schema/c&quot;
</code></pre>
<h2 id="Bean的作用域"><a href="#Bean的作用域" class="headerlink" title="Bean的作用域"></a>Bean的作用域</h2><p><img src="https://cdn.jsdelivr.net/gh/RhymeXmove/blogimg@latest/article/JAVA-Spring5-20210503/20200628180128654.png"></p>
<ol>
<li>单例模式（Spring默认机制）</li>
</ol>
<pre><code class="xml">&lt;bean id=&quot;user2&quot; class=&quot;com.kuang.pojo.User&quot; c:name=&quot;狂神2&quot; c:age=&quot;11&quot; scope=&quot;singleton&quot;/&gt;
</code></pre>
<ol start="2">
<li>原型模式：每次从容器中get的时候，都会产生一个新对象</li>
</ol>
<pre><code class="xml">&lt;bean id=&quot;user2&quot; class=&quot;com.kuang.pojo.User&quot; c:name=&quot;狂神2&quot; c:age=&quot;11&quot; scope=&quot;prototype&quot;/&gt;
</code></pre>
<ol start="3">
<li>其余的request、session、application这些只能在web开发中使用到</li>
</ol>
<h1 id="Bean的自动装配"><a href="#Bean的自动装配" class="headerlink" title="Bean的自动装配"></a>Bean的自动装配</h1><ul>
<li>自动装配是Spring满足bean依赖的一种方式</li>
<li>Spring会在上下文中自动寻找，并自动给bean装配属性</li>
</ul>
<p> 在Spring中有三种装配的方式</p>
<ol>
<li>在xml中显示的配置</li>
<li>在java中显示的配置</li>
<li>隐式的自动装配bean 【重要】</li>
</ol>
<h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><p>环境搭建：一个人有两个宠物</p>
<h2 id="byName自定装配"><a href="#byName自定装配" class="headerlink" title="byName自定装配"></a>byName自定装配</h2><pre><code class="xml">&lt;bean id=&quot;cat&quot; class=&quot;com.kuang.pojo.Cat&quot;/&gt;
&lt;bean id=&quot;dog&quot; class=&quot;com.kuang.pojo.Dog&quot;/&gt;

    &lt;!--
        byName : 会自动在容器上下文中查找，和自己对象set方法后面的值对应的bean_id
    --&gt;
&lt;bean id=&quot;people&quot; class=&quot;com.kuang.pojo.People&quot; autowire=&quot;byName&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;狂神&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<h2 id="byTpye自动装配"><a href="#byTpye自动装配" class="headerlink" title="byTpye自动装配"></a>byTpye自动装配</h2><pre><code class="xml">    &lt;!--
        byName : 会自动在容器上下文中查找，和自己对象set方法后面的值对应的bean_id
        byType : 会自动在容器上下文中查找，和自己对象属性类型相同的bean
    --&gt;
&lt;bean id=&quot;people&quot; class=&quot;com.kuang.pojo.People&quot; autowire=&quot;byType&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;狂神&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<p><strong>小结：</strong></p>
<ul>
<li>byName的时候，需要保证所有bean的id唯一，并且这个bean需要和自动注入的属性的set方法的值一致</li>
<li>byType的时候，需要保证所有bean的class唯一，并且这个bean需要和自动注入的属性的类型一致</li>
</ul>
<h2 id="使用注解实现自动装配"><a href="#使用注解实现自动装配" class="headerlink" title="使用注解实现自动装配"></a>使用注解实现自动装配</h2><p>jdk1.5支持的注解，Spring2.5就支持注解了！</p>
<p>要使用注解须知：</p>
<ol>
<li>导入约束</li>
<li>配置注解的支持 <a href="context:annotation-config/">context:annotation-config/</a></li>
</ol>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

    &lt;context:annotation-config/&gt;

&lt;/beans&gt;
</code></pre>
<h3 id="Autowired"><a href="#Autowired" class="headerlink" title="@Autowired"></a>@Autowired</h3><p>直接在属性上使用即可，也可以在set方法上使用</p>
<p>使用Autowired我们可以不用编写set方法了，前提是你这个自动装配的属性在 IOC（Spring）容器中存在，且符合名字byName</p>
<p>科普：</p>
<pre><code>@Nullable    字段标记了这个注解，说明这个字段可以为null;
</code></pre>
<pre><code class="java">public @interface Autowired &#123;
    boolean required() default true;
&#125;
</code></pre>
<p>测试代码：</p>
<pre><code class="java">public class People &#123;
    //如果显示定义了Autowired的required属性为false，说明这个对象可以为Null,否则不允许为空
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
&#125;
</code></pre>
<p>如果@Autowired自动装配的环境比较复杂，自动装配无法通过一个注解【**@Autowired<strong>】完成的时候，我们可以使用</strong>@Qualifier(value = “xxx”)**去配合@Autowire的使用，指定一个唯一的bean对象注入！</p>
<pre><code class="java">public class People &#123;

    @Autowired
    @Qualifier(value = &quot;cat2&quot;)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
&#125;
</code></pre>
<h3 id="Resource"><a href="#Resource" class="headerlink" title="@Resource"></a>@Resource</h3><pre><code class="java">public class People &#123;

    @Resource( name = &quot;cat3&quot;)
    private Cat cat;
    @Resource
    private Dog dog;
    private String name;
&#125;
</code></pre>
<p>小结：</p>
<p>@Resource和@Autowired的区别：</p>
<p>都是用来自动转配的，都可以放在属性字段上<br>@Autowired 是通过byType的方式实现，而且必须要求这个对象存在！【常用】<br>@Resource 默认通过byName的方式实现，如果找不到名字，则通过byType实现！如果两个都找不到的情况下，就报错！【常用】<br>执行顺序不同: @Autowired 通过byType的方式实现。@Resource默认通过byName的方式实现。</p>
<p>原理实现：通过反射机制来实现访问，所以不需要写set方法</p>
<p>可以配合@qualifier来指定一个唯一的bean对象注入</p>
<p>@Nullable 如果某个字段标记了这个注解后，说明这个字段可以为null</p>
<p>@Autowired 里面有个参数required可以为false，说明这个字段可以为null，否则不允许为空</p>
<p>@Resource注解 也可以实现和@autowired一样的功能</p>
<p>注意：@Resource注解是Java自带的注解</p>
<p>使用注解开发     </p>
<p>注解说明</p>
<p>@Component：组件，放在类上，说明这个类被Spring管理了就是Bean</p>
<p>衍生的注解</p>
<p>dao层     @Repository</p>
<p>service层  @Service</p>
<p>controller层  @Controller</p>
<p>@Value 可以用来注入属性   可以在setXXX()方法上直接注入值</p>
<p>@Scope 作用域注解 里面可以有prototype和singleton</p>
<p>xml与注解：</p>
<p>xml更加万能，适用于任何场合！</p>
<p>注解 不是自己的类使用不了 维护相对复杂</p>
<p>xml与注解最佳实践</p>
<p>1.xml用来管理bean</p>
<p>2.注解只负责完成属性的注入</p>
<p>3.在使用的过程，想让注解生效，必须开启对注解的支持</p>
<pre><code class="xml">&lt;context:component-scan base-package=&quot;com.shan.pojo&quot;/&gt;
&lt;context:annotation-config/&gt;
</code></pre>
<h1 id="Java类实现Spring配置"><a href="#Java类实现Spring配置" class="headerlink" title="Java类实现Spring配置"></a>Java类实现Spring配置</h1><pre><code class="java">@Configuration
@ComponentScan(&quot;pojo&quot;)
//这个类也会被注入到Spring容器中，其本质就是一个@Component
//@Configuration代表这是一个配置类，用于替代beans.xml
public class LewisConfig &#123;
    @Bean
    //注册一个bean，相当于xml里的一个bean标签
    //方法的名字相当于bean标签的id值
    //方法的返回类型相当于bean标签的class属性值
    public User getUser()&#123;
        return new User();
    &#125;
&#125;
</code></pre>
<p>使用下面的代码来获得Spring容器，同样用getBean方法来获得容器中的对象</p>
<pre><code class="java">ApplicationContext context = new AnnotationConfigApplicationContext(LewisConfig.class);
</code></pre>
<h1 id="面向切面编程AOP（重点）"><a href="#面向切面编程AOP（重点）" class="headerlink" title="面向切面编程AOP（重点）"></a>面向切面编程AOP（重点）</h1><ul>
<li>横切关注点：横跨多个模块的方法或功能，待加入到业务层实现功能扩充，如日志功能</li>
<li>切面（aspect）：横切关注点被模块化的特殊对象，是一个类，即下文中的afterLog类</li>
<li>通知（advice）：切面必须完成的工作，即类中的一个方法</li>
<li>目标（target）：被通知对象，下文中的UserServiceImpl类的对象</li>
<li>代理（proxy）：向目标对象加入通知创建的新对象</li>
<li>切入点（pointcut）：切面通知执行的“地点”的定义</li>
<li>连接点（jointpoint）：与切入点匹配的执行点</li>
</ul>
<h2 id="Spring-API接口实现"><a href="#Spring-API接口实现" class="headerlink" title="Spring API接口实现"></a>Spring API接口实现</h2><p>在保持service层代码不变的基础上，通过AOP新增一些其他的功能。</p>
<pre><code class="java">//UserService接口
public interface UserService &#123;
    public void add();
    public void delete();
    public void update();
    public void select();
&#125;
//UserServiceImpl实现类
public class UserServiceImpl implements UserService&#123;
    public void add() &#123;
        System.out.println(&quot;增加了一个用户&quot;);
    &#125;

    public void delete() &#123;
        System.out.println(&quot;删除了一个用户&quot;);
    &#125;

    public void update() &#123;
        System.out.println(&quot;修改了一个用户&quot;);
    &#125;

    public void select() &#123;
        System.out.println(&quot;查询了一个用户&quot;);
    &#125;
&#125;
//afterLog
public class afterLog  implements AfterReturningAdvice &#123;
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable &#123;
        System.out.println(&quot;执行了&quot;+method.getName()+&quot;方法，返回的结果为&quot;+returnValue);
    &#125;
&#125;
//beforeLog
public class beforeLog implements MethodBeforeAdvice &#123;
    public void before(Method method, Object[] objects, Object target) throws Throwable &#123;
        System.out.println(target.getClass().getName()+&quot;的&quot;+method.getName()+&quot;被执行了&quot;);
    &#125;
&#125;
</code></pre>
<p>xml配置文件</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
&quot;&gt;
&lt;!--    注册bean--&gt;
    &lt;bean id=&quot;userService&quot; class=&quot;com.lewis.service.UserServiceImpl&quot;/&gt;
    &lt;bean id=&quot;afterLog&quot; class=&quot;com.lewis.log.afterLog&quot;/&gt;
    &lt;bean id=&quot;beforeLog&quot; class=&quot;com.lewis.log.beforeLog&quot;/&gt;

    &lt;aop:config&gt;
        &lt;aop:pointcut id=&quot;pointcup&quot; expression=&quot;execution(* com.lewis.service.UserServiceImpl.*(..))&quot;/&gt;
        &lt;aop:advisor advice-ref=&quot;afterLog&quot; pointcut-ref=&quot;pointcup&quot;/&gt;
        &lt;aop:advisor advice-ref=&quot;beforeLog&quot; pointcut-ref=&quot;pointcup&quot;/&gt;
    &lt;/aop:config&gt;
&lt;/beans&gt;
</code></pre>
<h2 id="自定义实现AOP（主要是切面定义）推荐使用"><a href="#自定义实现AOP（主要是切面定义）推荐使用" class="headerlink" title="自定义实现AOP（主要是切面定义）推荐使用"></a>自定义实现AOP（主要是切面定义）推荐使用</h2><p>自定义接口类</p>
<pre><code class="java">public class DiyPointCut &#123;
    public void before()&#123;
        System.out.println(&quot;===========方法执行前================&quot;);
    &#125;
    public void after()&#123;
        System.out.println(&quot;===========方法执行后================&quot;);
    &#125;
&#125;
</code></pre>
<p>配置文件</p>
<pre><code class="xml">&lt;bean id=&quot;diy&quot; class=&quot;diy.DiyPointCut&quot;/&gt;
&lt;aop:config&gt;
    &lt;!--切面：一个类--&gt;
    &lt;aop:aspect ref=&quot;diy&quot;&gt;
    &lt;!--切入点--&gt;
        &lt;aop:pointcut id=&quot;point&quot; expression=&quot;execution(* service.UserServiceImpl.*(..))&quot;/&gt;
    &lt;!--通知--&gt;
        &lt;aop:after method=&quot;after&quot; pointcut-ref=&quot;point&quot;/&gt;
        &lt;aop:before method=&quot;before&quot; pointcut-ref=&quot;point&quot;/&gt;
    &lt;/aop:aspect&gt;
&lt;/aop:config&gt;
</code></pre>
<h2 id="使用注解实现AOP"><a href="#使用注解实现AOP" class="headerlink" title="使用注解实现AOP"></a>使用注解实现AOP</h2><p>在类上使用<code>@Aspect</code>，表明这个类是一个切面；在方法上使用<code>@Before,@After</code>等实现通知</p>
<pre><code class="xml">&lt;bean id=&quot;annotationPointCut&quot; class=&quot;service.UserServiceImpl&quot;/&gt;
&lt;!--开启注解支持--&gt;
&lt;aop:aspectj-autoproxy/&gt;
</code></pre>
<pre><code class="java">@Aspect
public class AnnotationPointCut &#123;
    @Before(&quot;execution(* service.UserServiceImpl.*(..))&quot;)
    public void before()&#123;
        System.out.println(&quot;===========方法执行前===========&quot;);
    &#125;
    @After(&quot;execution(* service.UserServiceImpl.*(..))&quot;)
    public void after()&#123;
        System.out.println(&quot;===========方法执行后===========&quot;);
    &#125;
     @Around(&quot;execution(* service.UserServiceImpl.*(..))&quot;)
    public void around()&#123;
        System.out.println(&quot;===========环绕后===========&quot;);
    &#125;
&#125;
</code></pre>

  </article>

  
    
  <div class="nexmoe-post-copyright">
    <strong>本文作者：</strong>shanX<br>
    <strong>本文链接：</strong><a href="https://rhymexmove.github.io/2021/05/03/33b6a07e76bd/" title="https:&#x2F;&#x2F;rhymexmove.github.io&#x2F;2021&#x2F;05&#x2F;03&#x2F;33b6a07e76bd&#x2F;" target="_blank" rel="noopener">https:&#x2F;&#x2F;rhymexmove.github.io&#x2F;2021&#x2F;05&#x2F;03&#x2F;33b6a07e76bd&#x2F;</a><br>
    
      <strong>版权声明：</strong>本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/cn/deed.zh" target="_blank">CC BY-NC-SA 3.0 CN</a> 协议进行许可
    
  </div>


  
  
  <div class="nexmoe-post-meta nexmoe-rainbow">
    
        <a class="nexmoefont icon-appstore-fill -link" href="/categories/java/">java</a>
    
    
        <a class="nexmoefont icon-tag-fill -none-link" href="/tags/java%E5%9F%BA%E7%A1%80/" rel="tag">java基础</a> <a class="nexmoefont icon-tag-fill -none-link" href="/tags/spring/" rel="tag">spring</a>
    
</div>

  <div class="nexmoe-post-footer">
    <section class="nexmoe-comment">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.min.css">
<div id="gitalk"></div>
<script src="https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.min.js"></script>
<script type="text/javascript">
    var gitalk = new Gitalk({
        clientID: 'a2d666d91d6af126f538',
        clientSecret: '9c79e44494cd9fae312629457ae9b534e01a963e',
        id: decodeURI(window.location.pathname),
        repo: 'RhymeXmove.github.io',
        owner: 'RhymeXmove',
        admin: 'RhymeXmove'
    })
    gitalk.render('gitalk')
</script>
</section>
  </div>
</div>
                            <div class="nexmoe-post-right">
                                <div class="nexmoe-fixed">
                                    <div class="nexmoe-tool">
                                        <a href="#nexmoe-content" class="toc-link" aria-label="回到顶部" title="top"><button class="mdui-fab mdui-ripple"><i class="nexmoefont icon-caret-top"></i></button></a>
                                    </div>
                                </div>
                            </div>
                    </div>
                </div>
                <script src="https://cdn.jsdelivr.net/combine/npm/lazysizes@5.1.0/lazysizes.min.js,gh/highlightjs/cdn-release@9.15.8/build/highlight.min.js,npm/mdui@0.4.3/dist/js/mdui.min.js?v=1"></script>
<script>
	hljs.initHighlightingOnLoad();
</script>

<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>


<script src="https://cdn.jsdelivr.net/gh/xtaodada/xtaodada.github.io@0.0.2/copy.js"></script>
 

<script src="/js/app.js?v=1649858550903"></script>

<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js"></script>
<script>
	$(".justified-gallery").justifiedGallery({
		rowHeight: 160,
		margins: 10,
	});
</script>

                    





        </body>

</html>